package conf

import (
	"errors"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"os"
	"strings"
)

func ParseExcel(file string) error {
	// 打开excel
	xlsx, err := excelize.OpenFile(file)
	if err != nil {
		fmt.Println("parse excel open file failed", err)
		return errors.New("open file failed")
	}

	// 创建conf文件
	base_name := strings.Split(file, ".")[0]
	conf_f, err := os.OpenFile(base_name+".conf", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		return errors.New("open excel result conf file failed")
	}
	defer conf_f.Close()

	// 创建proto文件
	proto_f, err := os.OpenFile(base_name+".proto", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		return errors.New("open excel result proto file failed")
	}
	defer proto_f.Close()

	// 读取excel数据
	cell := xlsx.GetRows("Data")
	row_len := len(cell)
	if row_len < 3 {
		return errors.New("not normal xlsx :" + file)
	}
	names := cell[0]
	who_use := cell[1]
	types := cell[2]
	col_len := len(cell[0])
	for i := 0; i < col_len; i++ {
		types[i] = strings.ToLower(types[i])
		who_use[i] = strings.ToLower(who_use[i])
		names[i] = strings.ToLower(names[i])
	}

	// 写proto文件
	fmt.Fprintln(proto_f, "message", base_name, "{")
	name_map := make(map[string]bool)
	for i := 0; i < col_len; i++ {
		if who_use[i] == "client" {
			continue
		}
		var s string
		real_name := names[i]
		real_type := types[i]
		switch types[i] {
		case "int32", "float", "string", "int64":
			s = "optional"
		case "array<int32>", "array<float>", "array<string>", "array<int64>":
			s = "repeated"
			real_type = strings.Split(strings.Split(types[i], "<")[1], ">")[0]
			real_name = strings.Split(real_name, "[")[0]
		}
		if _, b := name_map[real_name]; b {
			continue
		}
		name_map[real_name] = true
		fmt.Fprintf(proto_f, "    %s %s %s = %d;\n", s, real_type, real_name, len(name_map))
	}
	fmt.Fprintln(proto_f, "}")
	fmt.Fprintln(proto_f, "message "+base_name+"_array", "{")
	fmt.Fprintln(proto_f, "    repeated", base_name, base_name+"_list = 1;")
	fmt.Fprintln(proto_f, "}")

	// 写conf文件
	for i := 3; i < row_len; i++ {
		col_len := len(cell[i])
		fmt.Fprintln(conf_f, "{")
		for j := 0; j < col_len; j++ {
			if who_use[j] == "client" {
				continue
			}
			switch types[j] {
			case "int32", "float", "int64":
				fmt.Fprintf(conf_f, "    %s : %s\n", names[j], cell[i][j])
			case "array<int32>", "array<float>", "array<int64>":
				fmt.Fprintf(conf_f, "    %s : %s\n", strings.Split(names[j], "[")[0], cell[i][j])
			case "string":
				fmt.Fprintf(conf_f, "    %s : \"%s\"\n", names[j], cell[i][j])
			case "array<string>":
				fmt.Fprintf(conf_f, "    %s : \"%s\"\n", strings.Split(names[j], "[")[0], cell[i][j])
			default:
				return errors.New("not normal type:" + types[j])
			}
		}
		fmt.Fprintln(conf_f, "}")
	}
	return nil
}
